import { defineStore } from 'pinia'
import type { LoginParamsData, UserInfoData } from '@/api/userInfo'
import { default as userInfoApi } from '@/api/userInfo'
import {allAsyncRoutes, anyRoute, staticRoutes} from '@/router/routes'
import type { RouteRecordRaw } from 'vue-router'
import router from '@/router'
import cloneDeep from 'lodash/cloneDeep'


interface UserInfoStoreStateData {
  token: string,
  userInfo: UserInfoData,
  menuRoutes:Array<RouteRecordRaw>
}


function initUserInfo(target: UserInfoData, source: UserInfoData) {
  Object.assign(target, source)
}



// 定义函数从所有的异步路由当中过滤当前用户的异步路由
// function filterAsyncRoutes(allAsyncRoutes:RouteRecordRaw[],routeNames:string[]){
//   let asyncRoutes = allAsyncRoutes.filter(item => {
//     if(routeNames.indexOf(item.name as string) !== -1){
//       // 如果这么写，只能过滤出我们的一级路由，而二级路由我们没办法过滤出，所以还得过滤出二级路由
//       // 递归
//       if(item.children && item.children.length){
//         // 这里如果过滤出来，会把原本的所有的异步路由当中符合条件的那个二级路由给覆盖掉
//         // 后期如果使用admin再登录，admin当中二级路由会出问题，不全； 
//         item.children = filterAsyncRoutes(item.children,routeNames)
//       }
//       return true
//     }
//   })
//   return asyncRoutes
// }

// 封装可以一次性添加多个路由的工具函数
// function addRoutes(userAsyncRoutesAndAnyRoute:RouteRecordRaw[]){
//   userAsyncRoutesAndAnyRoute.forEach(item => {
//     router.addRoute(item)
//   })
// }

// 当用户退出登录的时候，我们需要重置路由
// function resetRoutes(){
//   // getRoutes(): RouteRecord[]获取路由器当中的所有路由
//   // removeRoute(name: string | symbol): void 根据路由的名称删除某个路由
//   // 1、先把路由器当中的所有路由删除
//   let routes = router.getRoutes()
//   routes.forEach(item => {
//     router.removeRoute(item.name as string)
//   })
//   // 2、在给路由器当中动态添加上staticRoutes
//   addRoutes(staticRoutes)
// }





export const useUserInfoStore = defineStore('userInfo', {
  // 核心概念
  state: (): UserInfoStoreStateData => {
    return {
      // token到时候要和自动登录（免登录）相关联
      // 存储token到localStorage持久化存储
      // cookie  localStorage  sessionStorage的区别
      token: localStorage.getItem('token_key') || '',
      userInfo: {
        routes: [],
        buttons: [],
        roles: [],
        name: '',
        avatar: ''
      },
      menuRoutes:staticRoutes
    }
  },
  actions: {
    async login(loginParams: LoginParamsData) {
      try {
        const result = await userInfoApi.userLogin(loginParams)
        this.token = result.token  //把token保存在state
        // 要自动登录还得把token保存到localStorage
        localStorage.setItem('token_key', result.token)

        // 如果登录成功，我们还要写一个正常的返回值，让async函数返回的promise是成功的
        // 后面根据这个值来判断登录成功还是失败，再去做后续的操作
        return 'ok'
      } catch (error) {
        return Promise.reject('登录失败')
      }
    },

    // 根据token获取用户信息
    async getUserInfo() {
      try {
        const result = await userInfoApi.getUserInfo()
        this.userInfo = result 
        let routeNames = result.routes
        // 过滤获取用户自己的异步路由
        // let userAsyncRoutes = filterAsyncRoutes(cloneDeep(allAsyncRoutes),routeNames)
        // addRoutes(userAsyncRoutes.concat(anyRoute))
        // 上面的动态添加我们也可以叫动态注册，注册上路由是让用户点击的时候有跳转功能
        // 但是并不能显示出菜单，显示菜单要依靠的是上面state当中的menuRoutes这个数据
        // 所以我们还要把menuRoutes这个数据给修改了
        // this.menuRoutes = staticRoutes.concat(userAsyncRoutes,anyRoute)

        return 'ok'
      } catch (error) {
        return Promise.reject('获取用户信息失败')
      }
    },

    async reset() {
      this.token = ''
      initUserInfo(this.userInfo, {
        routes: [],
        buttons: [],
        roles: [],
        name: '',
        avatar: ''
      })
      localStorage.removeItem('token_key')
    },

    async logout() {
      try {
        await userInfoApi.userLogout()
        // 退出成功我们需要把state当中的用户信息和token全部清除
        // 也得把localStorage当中的token给清除
        // this.token = ''
        // this.userInfo = {}
        // localStorage.removeItem('token_key')

        // 重置路由
        // resetRoutes()
        this.reset()
        return 'ok'
      } catch (error) {
        return Promise.reject('退出失败')
      }
    }
  },
  getters: {

  }
})